package JasPerl::JSTL::Fmt::FormatDateTag;

use 5.010;
use strict;
use warnings;

use parent qw(JasPerl::TagExt::JspTag);

use JasPerl::JSTL::Core::Config qw(:fmt);
use JasPerl::JSTL::Fmt::DateFormat;
use JasPerl::JSTL::Fmt::LocalizationContext;

use JasPerl::PageContext qw(:scopes);

use JasPerl::Util::Date;
use JasPerl::Util::TimeZone;

my $BUNDLE_CLASS = 'JasPerl::JSTL::Fmt::BundleTag';
my $TIME_ZONE_CLASS = 'JasPerl::JSTL::Fmt::TimeZoneTag';

my %TYPES = (
    date => sub {
        my ($self, $locale) = @_;
        my $style = $self->{date_style};
        return JasPerl::JSTL::Fmt::DateFormat->get_date_format($style, $locale);
    },
    time => sub {
        my ($self, $locale) = @_;
        my $style = $self->{time_style};
        return JasPerl::JSTL::Fmt::DateFormat->get_date_format($style, $locale);
    },
    both => sub {
        my ($self, $locale) = @_;
        my $style = $self->{date_style} // $self->{time_style};
        return JasPerl::JSTL::Fmt::DateFormat->get_format($style, $locale);
    }
);

sub set_date_style {
    $_[0]->{date_style} = $_[1];
}

sub set_pattern {
    $_[0]->{pattern} = $_[1];
}

sub set_scope {
    $_[0]->{scope} = JasPerl::PageContext->get_scope_by_name($_[1]);
}

sub set_type {
    $_[0]->{type} = $_[1];
}

sub set_time_style {
    $_[0]->{time_style} = $_[1];
}

sub set_time_zone {
    $_[0]->{time_zone} = JasPerl::Util::TimeZone->from($_[1]);
}

sub set_value {
    $_[0]->{value} = JasPerl::Util::Date->from($_[1]);
}

sub set_var {
    $_[0]->{var} = $_[1];
}

sub get_locale {
    my $self = shift;
    my $pc = $self->get_jsp_context();
    if (my $parent = $self->find_ancestor_isa($BUNDLE_CLASS)) {
        return $parent->get_bundle()->get_locale();
    } else {
        return JasPerl::JSTL::Fmt::LocalizationContext->get_bundle($pc)->get_locale();
    }
}

sub get_time_zone {
    my $self = shift;
    if ($self->{time_zone}) {
        return $self->{time_zone};
    } elsif (my $parent = $self->find_ancestor_isa($TIME_ZONE_CLASS)) {
        return $parent->get_time_zone();
    } elsif (my $tz = JasPerl::JSTL::Core::Config->find($self->get_jsp_context(), FMT_TIME_ZONE)) {
        return JasPerl::Util::TimeZone->from($tz);
    } else {
        return JasPerl::Util::TimeZone->get_default();
    }
}

sub get_format {
    my ($self, $locale) = @_;
    if (defined $self->{pattern}) {
        return JasPerl::JSTL::Fmt::DateFormat->new($self->{pattern}, $locale);
    } elsif (my $method = $TYPES{$self->{type} // 'date'}) {
        return $self->$method($locale);
    } else {
        die "no type";
    }
}

sub do_tag {
    my $self = shift;
    my $context = $self->get_jsp_context();

    # FIXME required value
    $self->{value} //= JasPerl::Util::Date->new();

    if (defined $self->{value}) {
        my $format = $self->get_format($self->get_locale());
        $format->set_time_zone($self->get_time_zone());
        my $date = $format->format($self->{value});

        if (defined $self->{var}) {
            $context->set_attribute($self->{var}, $date, $self->{scope});
        } else {
            $context->get_out()->print($date);
        }
    } elsif (defined $self->{var}) {
        $context->remove_attribute($self->{var}, $self->{scope} // PAGE_SCOPE);
    }
}

1;
